﻿module Mapparola.Client {

    export class LiveView extends View {

        private discussions: KnockoutObservableArray<Core.Client.DiscussionC>;

        private minMapHeightPX: number;
        private maxMapHeightPX: number;
        private mapContainerHeight: number;
        private msgContainerHeight: number;

        private handlerPosition: number;

        private msgOpenerContainer: JQuery;

        private msgEditorIsOpened: KnockoutObservable<boolean>;
        private newMsgText: KnockoutObservable<string>;
        private isPinned: KnockoutObservable<boolean>;

        constructor(app: Mapparola.Client.App) {

            var el = $("#live-view").get(0);
            super(el, app);

            this.msgOpenerContainer = $(".message-opener-container", this.viewEl);

            this.AttachResizer();

            this.discussions = ko.observableArray<Core.Client.DiscussionC>();
            this.newMsgText = ko.observable<string>();
            this.isPinned = ko.observable<boolean>(false);
            this.msgEditorIsOpened = ko.observable<boolean>(false);

            ko.applyBindings(this, this.viewEl);

            PubSub.subscribe("UserRetrieved", (msg: string, user: Core.User) => {
                if (user) {
                    this.GetNewDiscussionsAroundMe();
                }
            });
        }

        public ActivatePage(): void {

            if (this._app.ActivePage) {
                this._app.DeactivateView(this._app.ActivePage.viewEl);
            }
            this._app.ActivePage = this;
            this._app.ActivateView(this._app.ActivePage.viewEl);

            window.setTimeout(() => {
                this._app.Mapping.RefreshMap();

                this.minMapHeightPX = $(this.viewEl).height() * 30 / 100;
                this.maxMapHeightPX = $(this.viewEl).height() * 70 / 100;

            }, 500);

        }

        private AttachResizer(): void {

            var resizerEl = $(".map-resizer", this.viewEl);

            var mapContainer = $(".map-container", this.viewEl);
            var msgContainer = $(".msg-container", this.viewEl);

            resizerEl.draggable(
                {
                    axis: "y",
                    start: (event: Event, ui: JQueryUI.DraggableEventUIParams) => {
                        this.mapContainerHeight = mapContainer.height();
                        this.msgContainerHeight = msgContainer.height();

                        this.handlerPosition = ui.position.top;
                    },

                    drag: (event: Event, ui: JQueryUI.DraggableEventUIParams) => {
                        var heightOffset = ui.position.top - this.handlerPosition;
                        this.handlerPosition = ui.position.top;
                        console.log(heightOffset);

                        if (this.mapContainerHeight + heightOffset < this.maxMapHeightPX &&
                            this.mapContainerHeight + heightOffset > this.minMapHeightPX) {

                            this.mapContainerHeight += heightOffset;
                            this.msgContainerHeight -= heightOffset;

                            mapContainer.height(this.mapContainerHeight);
                            msgContainer.height(this.msgContainerHeight);

                            return true;
                        }
                        else {
                            return false;
                        }
                    },
                    stop: (event: Event, ui: any) => {
                        this._app.Mapping.RefreshMap();
                    }
                });
        }

        private ToggleMsgEditorVisibility(): void {

            this.msgEditorIsOpened(!this.msgEditorIsOpened());

        }

        private SendNewMessage(): void {

            var text = this.newMsgText();

            //Create an obj of type discussionC to update the UI
            var newDiscussionC = new Core.Client.DiscussionC();
            newDiscussionC.SetText(text);
            newDiscussionC.CreatedDate = moment().utc().toDate();
            newDiscussionC.Location = this._app.Mapping.GetCurrentPoint();

            //Create an obj of type discussion for the server
            var newDiscussion = new Core.Discussion();
            newDiscussion.SetText(text);
            newDiscussion.CreatedDate = moment().utc().toDate();
            newDiscussion.Location = this._app.Mapping.GetCurrentPoint();

            //Add at the beginning of the array
            this.discussions.unshift(newDiscussionC);

            //Close editor if option is not pinned
            if (!this.isPinned()) {
                this.msgEditorIsOpened(false);
            }

            //Reset editor
            this.newMsgText("");

            //Make server request
            var args: Core.Client.AjaxRequestArgs = {
                data: newDiscussion,
                success: () => {
                    console.log("new message sent with success");
                },
                error: () => {
                    console.log("new message send failed");
                },
            };

            this._app.RestDataStore.PostNewDiscussion(newDiscussion, args);
        }

        private GetNewDiscussionsAroundMe(): void {

            var args: Core.Client.AjaxRequestArgs = {
                beforeSend: () => {

                },
                success: (discussions: Core.Client.DiscussionC[]) => {
                    this._app.Mapping.RenderMessages(discussions);

                    discussions.forEach((value: Core.Client.DiscussionC) => {
                        this.discussions.push(value);
                    });

                },
                error: () => {
                    console.log("error");
                }
            }
            
            this._app.Mapping.GetPosition(() => {
                this._app.RestDataStore.GetNewDiscussionsAroundMe(this._app.Mapping.GetCurrentPoint(), args);
            });

        }

        private PanToDiscussion(discussion: Core.Client.DiscussionC, e: Event) {

            console.log("clicked");

            this._app.Mapping.Center(discussion.Location.x, discussion.Location.y, 19);

        }

        private FavoriteDiscussion(discussion: Core.Client.DiscussionC, e: Event) {

            console.log("dblClicked");
            discussion.Favorite();

            var args: Core.Client.AjaxRequestArgs = {
                success: () => {
                    console.log("new message sent with success");
                },
                error: () => {
                    console.log("new message send failed");
                }
            };

            this._app.RestDataStore.FavoriteDiscussions(discussion.Token, args);

        }

        private ShowDiscussion(discussion: Core.Client.DiscussionC, e: Event) {

            PubSub.publish("ShowDiscussion", discussion);
            this._app.OpenPanel();
        }

    }
}